package com.file.transfers.socket;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.file.transfers.Main;

public class FileTransfersServer {
	private  int port;
	private  String filePath;
	private static int waitTimeOut=Main.properties.getInt("waitTimeOut");
	private static String separator = "/";
	private boolean running=false;
	public FileTransfersServer(int port,String filePath){
		this.port=port;
		this.filePath=filePath;
	}
	
	private ServerSocket serverSocket;
	public void start() {
		if(!running){
			running=true;
			new Thread(new SocketServer()).start();
		};
	}
	class SocketServer implements Runnable{
		@Override
		public void run() {
			try {
				 serverSocket=new ServerSocket(port);
				 System.out.println("Server:文件接收服务启动成功："+port);
					while(running){
						Socket accept = serverSocket.accept();
						String  str= accept.getRemoteSocketAddress().toString();
						long currentTimeMillis = System.currentTimeMillis();
						System.out.println("Server:接收到来自"+str+"的请求,Socket:"+accept.hashCode()+",时间："+currentTimeMillis);
						Thread thread=new Thread(new SocketAction(accept));
						thread.setName("SocketAction-"+str+"-"+currentTimeMillis);
						System.out.println("Server:接收到来自"+str+"的请求,启动新的线程");
						thread.start();
					}
				} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	public static String createFile(String filePath,String fileName,String separator){
		String str=filePath+separator+fileName;
		if(!"".equals(fileName)){
			File file = new File(filePath+separator+fileName);
			boolean exists = file.exists();
			if(!exists){
				file.mkdirs();
			}
		}
		str=str+separator;
		//System.out.println(str);
		return str;
	}
	public String splitFileName(String filename){
		int indexOf = filename.indexOf("/");
		String substring = filename.substring(indexOf+1);
		return substring;
		
	}
	class SocketAction implements Runnable{
		private List<String> fileList=new ArrayList<String>();
		private Socket s;
		private boolean run=true;
		private boolean isFirst=true;
		
		public List<String> getFileList() {
			return fileList;
		}
		public void setFileList(List<String> fileList) {
			this.fileList = fileList;
		}
		SocketAction(Socket s){
			this.s=s;
		}
		@Override
		public void run() {
			InputStream in = null;
			ObjectInputStream objectInputStream=null;
			try {
				in = s.getInputStream();
				s.setSoTimeout(waitTimeOut);
				objectInputStream=new ObjectInputStream(in);
			} catch (IOException e1) {
				run=false;
				try {
					s.close();
					s=null;
					objectInputStream=null;
				} catch (IOException e2) {
					e2.printStackTrace();
				}
				e1.printStackTrace();
			}
				while(running && run){
					FileOutputStream fileOutputStream=null;
					try {
						if(objectInputStream.read()!=-1){
							long startTimeMillis = System.currentTimeMillis();
							if(isFirst){
								String fileLists = objectInputStream.readUTF();
								String[] split = fileLists.split(",");
								System.out.println("Server:发送的文件列表："+fileLists);
								for (int i = 0; i < split.length; i++) {
									fileList.add(split[i]);
								}
								isFirst=false;
							}
							System.out.println("Server:--------------");
							String fileNames = objectInputStream.readUTF();
							long fileLength = objectInputStream.readLong();
							String[] split = fileNames.split("#");
							String splitFileName=split[0];
							String fileName=split[1];
							//System.out.println(fileName);
							/*if("009.PDF".equals(fileName)){
								System.out.println(fileName);
							}*/
							String createFile = createFile(filePath,splitFileName,separator);
							System.out.println("Server:"+filePath+splitFileName);
							File createTempFile = File.createTempFile(fileName, null,new File(createFile));
							fileOutputStream=new FileOutputStream(createTempFile);
							int old=0;
							int length=1024;
							if(fileLength+1<1024)length=(int) fileLength;
							int readLength=length;
							int spareFileLength=(int) fileLength;
							int readedLength=0;
							boolean isOver=true;
							//System.out.println("文件名："+fileName+",文件大小："+fileLength+",length="+length);
							byte[] b=new byte[length];
							int read = objectInputStream.read(b,0,readLength);
							while(read!=-1 && isOver){
								if(read<=readLength)readLength=read;
								spareFileLength=spareFileLength-readLength;
								readedLength=readedLength+readLength;
								if(spareFileLength<readLength)readLength=spareFileLength;
								if(spareFileLength==0)isOver=false;
								fileOutputStream.write(b,0,read);
								fileOutputStream.flush();
								Arrays.fill(b, (byte)0);
								read = objectInputStream.read(b,0,readLength);
								int tmp=(int) (readedLength*100.0/fileLength);
								//System.out.println(readedLength*100/fileLength+","+tmp%5);
								if((tmp%5==0)){
									if(old!=tmp){
										System.out.println("Server:\t文件名："+fileName+"，已完成："+tmp+"%");
										old=tmp;
									}
								}
									
							};
							
							fileOutputStream.flush();
							fileOutputStream.close();
							//System.out.println("重命名文件createTempFile="+createTempFile.getPath());
							//System.out.println("重命名文件createFile+fileName="+createFile+fileName);
							createTempFile.renameTo(new File(createFile+fileName));
							long endTimeMillis = System.currentTimeMillis();
							double time=(endTimeMillis-startTimeMillis)/1000.0;
							System.out.println("Server:文件名："+fileName+"传输完毕，耗时："+time+"s");
							
						}else{
						/*	try {
								Thread.sleep(waitTimeOut);
							} catch (InterruptedException e) {
							}
							System.out.println("Server:超时退出");*/
							run=false;
							if(s!=null)s.close();
							if(fileOutputStream!=null)fileOutputStream.close();
							fileOutputStream=null;
							s=null;
							System.out.println("Server:关闭连接");
						}
					} catch (IOException e) {
						run=false;
						try {
							if(s!=null)s.close();
							if(fileOutputStream!=null)fileOutputStream.close();
							fileOutputStream=null;
							s=null;
						} catch (IOException e1) {
							e1.printStackTrace();
						}
						e.printStackTrace();
					}
				}
				
			
		}
	}
	public static void main(String[] args) {
		FileTransfersServer  FileTransfersServer=new FileTransfersServer(8888,"E:\\jieshouwenjian");
		FileTransfersServer.start();
	}
}
	
